package com.promise.jokerdream.work.penguin

import com.promise.jokerdream.database.entity.PenguinFightGameConfigEntity
import com.promise.jokerdream.manager.ExecutionHistoryManager
import com.promise.jokerdream.model.boss.PenguinBossMapping
import com.promise.jokerdream.repository.GameApi
import com.promise.jokerdream.repository.PhoneGameApi
import com.promise.jokerdream.utils.UrlFixer
import com.promise.jokerdream.response.phone.FriendListXmlResponse
import com.promise.jokerdream.response.phone.FactionFriendXmlResponse
import com.promise.jokerdream.response.phone.XiaLvXmlResponse
import com.promise.jokerdream.response.phone.QueryAssistantXmlResponse
import com.promise.jokerdream.utils.AppContext
import com.promise.jokerdream.work.BaseWork
import com.promise.jokerdream.work.WorkResult

// 游戏数据容器
private data class GameData(
    val friendResult: Result<FriendListXmlResponse>,
    val factionResult: Result<FactionFriendXmlResponse>,
    val xiaLvResult: Result<XiaLvXmlResponse>,
    val assistantData: AssistantData
)

// Boss数据容器
private data class BossData(
    val bossFightUrls: List<String>
)

// 关系数据容器
private data class RelationData(
    val marryFightUrls: List<String>,
    val shituFightUrls: List<String>,
    val brotherFightUrls: List<String>
)

// 助手数据容器
private data class AssistantData(
    val contributionPotionEnabled: Boolean,
    val contributionPotionUrl: String?
)

/**
 * 自动乐斗工作
 * 支持 Boss 挑战、侠侣乐斗、师徒乐斗、结拜乐斗
 */
class PenguinFightAutoWork(
    private val config: PenguinFightGameConfigEntity,
    uin: String
): BaseWork(uin) {
    
    private val gameApi = GameApi.getInstance()
    private val phoneGameApi = PhoneGameApi.getInstance()
    private val historyManager by lazy { ExecutionHistoryManager.getInstance(AppContext.get()) }
    
    override val name: String
        get() = "乐斗"
    
    override suspend fun executeWork(): WorkResult {
        return try {
            // 1. 获取基础数据
            val gameData = fetchGameData()
            
            // 2. 解析boss和关系信息
            val bossData = parseBossData(gameData)
            val relationData = parseRelationData(gameData)
            
            // 3. 管理贡献药水设置
            manageContributionPotion(gameData.assistantData)
            
            // 4. 执行所有挑战
            val allFightUrls = mutableListOf<String>()
            
            // 添加Boss挑战链接
            if (config.bossEnabled) {
                allFightUrls.addAll(bossData.bossFightUrls)
            }
            
            // 添加羁绊挑战链接
            if (config.marryEnabled) {
                allFightUrls.addAll(relationData.marryFightUrls)
            }
            
            if (config.shituEnabled) {
                allFightUrls.addAll(relationData.shituFightUrls)
            }
            
            if (config.brotherEnabled) {
                allFightUrls.addAll(relationData.brotherFightUrls)
            }
            
            // 执行所有挑战链接
            if (allFightUrls.isNotEmpty()) {
                executeFightUrls(allFightUrls)
            }
            
            // 5. 挑战完成后恢复贡献药水设置
            restoreContributionPotion(gameData.assistantData)
            
            WorkResult.Success
        } catch (e: Exception) {
            WorkResult.Failure(e, e.message)
        }
    }
    
    /**
     * 获取游戏数据
     */
    private suspend fun fetchGameData(): GameData {
        // 获取好友信息
        val friendResult = phoneGameApi.queryFriendListData(1)
        friendResult.fold(
            onSuccess = { },
            onFailure = { exception ->
                historyManager.addHistory(name, exception.message)
            }
        )
        
        // 获取帮友信息
        val factionResult = phoneGameApi.queryFactionFriendData(1)
        factionResult.fold(
            onSuccess = { },
            onFailure = { exception ->
                historyManager.addHistory(name, exception.message)
            }
        )
        
        // 获取侠侣信息
        val xiaLvResult = phoneGameApi.queryXiaLvData()
        xiaLvResult.fold(
            onSuccess = { },
            onFailure = { exception ->
                historyManager.addHistory(name, exception.message)
            }
        )
        
        // 获取助手数据
        val assistantData = fetchAssistantData()
        
        return GameData(friendResult, factionResult, xiaLvResult, assistantData)
    }
    
    /**
     * 解析Boss数据
     */
    private suspend fun parseBossData(gameData: GameData): BossData {
        val bossFightUrls = mutableListOf<String>()
        
        // 从好友列表获取Boss挑战链接
        gameData.friendResult.fold(
            onSuccess = { response ->
                // 侠列表中的Boss（只添加未乐斗的）
                bossFightUrls.addAll(
                    response.xiaList.filter { !it.isFought }.map { it.fightUrl }
                )
            },
            onFailure = { exception ->
                historyManager.addHistory(name, exception.message)
            }
        )
        
        // 从帮友列表获取Boss挑战链接
        gameData.factionResult.fold(
            onSuccess = { response ->
                // Boss列表中的挑战链接（只添加未乐斗的）
                bossFightUrls.addAll(
                    response.factionBossList.filter { !it.isFought }.map { it.fightUrl }
                )
            },
            onFailure = { exception ->
                historyManager.addHistory(name, exception.message)
            }
        )
        
        // 从侠侣数据获取Boss挑战链接
        gameData.xiaLvResult.fold(
            onSuccess = { response ->
                // 侠侣中的Boss列表（只添加未乐斗的）
                if (response.marry != null) {
                    bossFightUrls.addAll(
                        response.bossList.filter { !it.isFought }.map { it.fightUrl }
                    )
                }
            },
            onFailure = { exception ->
                historyManager.addHistory(name, exception.message)
            }
        )
        
        return BossData(bossFightUrls)
    }
    
    /**
     * 解析羁绊数据
     */
    private fun parseRelationData(gameData: GameData): RelationData {
        val marryFightUrls = mutableListOf<String>()
        val shituFightUrls = mutableListOf<String>()
        val brotherFightUrls = mutableListOf<String>()
        
        // 从侠侣数据获取羁绊挑战链接
        gameData.xiaLvResult.fold(
            onSuccess = { response ->
                // 侠侣（情）挑战链接
                response.marry?.let { qingLv ->
                    if (!qingLv.isFought) {
                        marryFightUrls.add(qingLv.fightUrl)
                    }
                }
                
                // 师徒挑战链接
                response.shiFu?.let { shiFu ->
                    if (!shiFu.isFought) {
                        shituFightUrls.add(shiFu.fightUrl)
                    }
                }
                response.tuDiList.filter { !it.isFought }.forEach { tuDi ->
                    shituFightUrls.add(tuDi.fightUrl)
                }
                
                // 结拜挑战链接
                response.brotherList.filter { !it.isFought }.forEach { brother ->
                    brotherFightUrls.add(brother.fightUrl)
                }
            },
            onFailure = { exception ->
                historyManager.addHistory(name, exception.message)
            }
        )
        
        return RelationData(marryFightUrls, shituFightUrls, brotherFightUrls)
    }
    
    /**
     * 执行所有挑战链接
     */
    private suspend fun executeFightUrls(fightUrls: List<String>): WorkResult {
        return try {
            for (fightUrl in fightUrls) {
                // 使用UrlFixer修复URL
                val fixedUrl = UrlFixer.fixUrl(fightUrl)
                
                // 验证URL是否有效
                if (!UrlFixer.isValidUrl(fixedUrl)) {
                    historyManager.addHistory(name, "无效URL: $fixedUrl")
                    continue
                }
                
                // 使用fightFriend方法访问挑战链接
                val result = phoneGameApi.fightFriend(fixedUrl)
                result.fold(
                    onSuccess = { response ->
                        historyManager.addHistory(name, response.actionResult)
                    },
                    onFailure = { exception ->
                        historyManager.addHistory(name, exception.message)
                    }
                )
            }
            
            WorkResult.Success
        } catch (e: Exception) {
            WorkResult.Failure(e, e.message)
        }
    }
    
    /**
     * 获取助手数据
     */
    private suspend fun fetchAssistantData(): AssistantData {
        var contributionPotionEnabled = false
        var contributionPotionUrl: String? = null
        
        if (config.bossEnabled || config.marryEnabled || config.shituEnabled || config.brotherEnabled) {
            val assistantResult = phoneGameApi.queryAssistant()
            assistantResult.fold(
                onSuccess = { assistantResponse ->
                    val contributionLink = assistantResponse.findAssistant("贡献药水")
                    if (contributionLink != null) {
                        contributionPotionEnabled = contributionLink.enabled
                        contributionPotionUrl = contributionLink.url
                    }
                },
                onFailure = { exception ->
                    historyManager.addHistory(name, exception.message)
                }
            )
        }
        
        return AssistantData(contributionPotionEnabled, contributionPotionUrl)
    }
    
    /**
     * 管理贡献药水设置
     */
    private suspend fun manageContributionPotion(assistantData: AssistantData) {
        if (assistantData.contributionPotionUrl != null && !assistantData.contributionPotionEnabled) {
            phoneGameApi.accessAssistantLink(assistantData.contributionPotionUrl).fold(
                onSuccess = { response ->
                    if (response.actionResult.isNotEmpty()) {
                        historyManager.addHistory(name, response.actionResult)
                    }
                },
                onFailure = { exception ->
                    historyManager.addHistory(name, exception.message)
                }
            )
        }
    }
    
    /**
     * 恢复贡献药水设置
     */
    private suspend fun restoreContributionPotion(assistantData: AssistantData) {
        if (assistantData.contributionPotionUrl != null && !assistantData.contributionPotionEnabled) {
            phoneGameApi.accessAssistantLink(assistantData.contributionPotionUrl).fold(
                onSuccess = { response ->
                    if (response.actionResult.isNotEmpty()) {
                        historyManager.addHistory(name, response.actionResult)
                    }
                },
                onFailure = { exception ->
                    historyManager.addHistory(name, exception.message)
                }
            )
        }
    }
}